/*
- Malt Project - list.cpp
- This document is protected by the GPL protocol.
- Writer:@Index-Flandre
*/

#include "../../include/object/list.hpp"
//#include "../../include/object/objectpool.hpp"

namespace malt
{
//ObjPool<List> ListObjectPool;

Object *NewList()
{
	List *ls = new List();
	ls->tp = &ListType;
	return ls;
	return ls;
}

bool List::eq(Object *obj)
{
	if (tp != obj->tp)
		return false;
	if (this->size != ((List *)obj)->size)
		return false;
	Node *tp = first, *tp1 = ((List *)obj)->first;
	for (size_t i = 0; i < size; i++)
	{
		if (!tp->obj->eq(tp1->obj))
			return false;
		tp = tp->next;
	}
	return true;
}

void List::repl_print()
{
	printf("\e[0m(");
	Node *tp = first;
	for (size_t i = 0; tp != NULL; i++)
	{
		if (i != 0)
			printf(" ");
		if (tp->obj == NULL)
			printf("\e[34;1mnull\e[0m");
		else if (tp->obj == this)
			printf("(...)");
		else
			tp->obj->repl_print();
		tp = tp->next;
	}
	printf("\e[0m)");
}

Object *List::car()
{
	if (size < 1)
		return MaltNullptr;
	else
		return first->obj;
}
Object *List::to_last()
{
	if (last == 0)
		return ((Object *)0);
	else
		return last->obj;
}
Object *List::cdr()
{
	if (size < 2)
	{
		return MaltNullptr;
	}
	else if (size == 2)
	{
		return last->obj;
	}
	else
	{
		List *listo = (List *)NewList();
		listo->first = first->next;
		listo->last = last;
		listo->first->use_size++;
		listo->last->use_size++;
		listo->size = size - 1;
		return listo;
	}
}
void List::append(Object *obj)
{
	if (size == 0)
	{
		last = first = new Node();
		last->obj = obj;
		last->use_size = 2;
	}
	else
	{
		last->append(new Node);
		last = last->next;
		last->obj = obj;
		last->next = 0;
	}
	size++;
}
}